import { COMPONENT_TYPES } from '@/common/const-wb'
import { mapGetters } from 'vuex'
import { PAGE_TYPE } from '@/common/const'
import { MOBILE_WID_HEI } from '@/common/const-dif'
import { EventBus } from '@/store/index'
import { isJSON } from '@/plugins/utils'
import { isHasOwnProperty } from '@/plugins/utils'


export const pageAnimate = {
  created () {
    const data_ = {
      loadPageIndex: 0,
      isMountLoading: true,
      isFirst: true,
      gsapStaggers: {},
      gsapPaths: {},
      loadImgCompId: {},
      gsapSplitTexts: {},
    };
    for(let key in data_) {
      this[key] = data_[key];
    }
  },
  computed: {
    ...mapGetters({
      globalCurrentPage: "getCurrentPage",
    }),
  },
  methods: {
    initPlayAllAnimates(currentPageDom){
      if(this.animates.isGroupGsap[this.globalCurrentPage.id] || this.animates.isGsap[this.globalCurrentPage.id] || this.animates.isSplitGsap[this.globalCurrentPage.id]){
        if(window.gsap){
          this.prepareGsap(currentPageDom);
        }else{
          this.loadGsapCb = window.setInterval(() => {
            if(window.gsap){
              window.clearInterval(this.loadGsapCb);
              this.prepareGsap(currentPageDom);
            }
          }, this.siteInfo.reloadTime)
        }
      }
      if(this.animates.isAnimate[this.globalCurrentPage.id]){
        if(this.siteAttrs.pageType == PAGE_TYPE.long) {
          this.playAnimates(currentPageDom);
        } else {
          let elements = currentPageDom.getElementsByClassName("css-animate");
          _.forEach(elements, (element) => {
            EventBus.$emit("playCssAnimate", { id: element.id })
          })
        }
      }
    },
    prepareGsap(currentPageDom){

      if(this.animates.isPathBezier[this.globalCurrentPage.id]){
        if(window.MotionPathPlugin){
          window.gsap.registerPlugin(window.MotionPathPlugin);
        }
      }
      this.playGsapsCb = window.setInterval(() => {
        //页面还没有渲染完
        //页面内的组件还没有渲染完
        let groupGsaps = currentPageDom.getElementsByClassName("group-gsap");
        let compGsaps = currentPageDom.getElementsByClassName("component-gsap");
        let splitTextGsaps = currentPageDom.getElementsByClassName("split-text-gsap");
        if(this.animates.isGsap[this.globalCurrentPage.id]){
          if(compGsaps.length > 0) {
            window.clearInterval(this.playGsapsCb);
            this.kindsGsaps(window.gsap, currentPageDom);
          }
        }else{
          if(groupGsaps.length > 0 || splitTextGsaps.length > 0){
            window.clearInterval(this.playGsapsCb);
            this.kindsGsaps(window.gsap, currentPageDom);
          }
        }
      }, this.siteInfo.reloadTime)
    },
    playAnimates(currentPageDom){
      let viewHeight = MOBILE_WID_HEI.clientHeight;
      let viewTop = document.documentElement.scrollTop || document.body.scrollTop;
      let viewBottom = viewTop + viewHeight;
      
      let elements = currentPageDom.getElementsByClassName("scroll-animate");
      _.forEach(elements, (element) => {
        let elementHeight = element.clientHeight;
        let elementTop = element.offsetTop;
        let elementBottom = elementTop + elementHeight;

        if ((elementBottom >= viewTop) && (elementTop <= viewBottom)) {
          EventBus.$emit("playCssAnimate", { id: element.id })
          // element.style.visibility = 'visible';
          // const animateClass = element.getAttribute('data-animate-name');
          // element.style['animation-name'] = animateClass;
          // element.style['-webkit-animation-name'] = animateClass;
        }else {
          // element.style.visibility = 'hidden';
          // element.style['animation-name'] = '';
          // element.style['-webkit-animation-name'] = '';
        }
      });
    },
    kindsGsaps(gsap, currentPageDom){
      if(this.animates.isGroupGsap[this.globalCurrentPage.id]){
        const groupDoms = currentPageDom.getElementsByClassName("group-gsap");
        this.playGsapsByDom(gsap, groupDoms, this.loadAllImgPlayGsapStagger);
      }
      if(this.animates.isGsap[this.globalCurrentPage.id]){
        const compDoms = currentPageDom.getElementsByClassName("component-gsap");
        this.playGsapsByDom(gsap, compDoms, this.loadImgPlayGsap);
      }
      if(this.animates.isSplitGsap[this.globalCurrentPage.id]){
        const textDoms = currentPageDom.getElementsByClassName("split-text-gsap");
        this.playGsapSplitText(gsap, textDoms);
      }
    },
    playGsapsByDom(gsap, doms, loadCb){
      const viewHeight = MOBILE_WID_HEI.clientHeight;
      const viewTop = document.documentElement.scrollTop || document.body.scrollTop;
      const viewBottom = viewTop + viewHeight;

      _.forEach(doms, (dom) => {
        const componentData = this.componentMap[dom.id];
          if(this.siteAttrs.pageType == PAGE_TYPE.long && this.statePopId <= 0){
            const elementHeight = dom.clientHeight;
            const elementTop = dom.offsetTop;
            const elementBottom = elementTop + elementHeight;
            
            if ((elementBottom >= viewTop) && (elementTop <= viewBottom)) {
              if(componentData.commonAttr.isPlayGsap){
                loadCb(gsap, componentData, dom);
                componentData.commonAttr.isPlayGsap = false;
              }
            }else{
              componentData.commonAttr.isPlayGsap = true;
            }
          }else{
            loadCb(gsap, componentData, dom);
          }
      });
    },
    loadImgPlayGsap(gsap, componentData, pathDom){
      if(componentData.cid == COMPONENT_TYPES.wb_img){
        this["loadImgCb-" + componentData.id] = window.setInterval(() => {
          if(componentData.commonAttr.isLoadedImg){
            window.clearInterval(this["loadImgCb-" + componentData.id]);
            if(componentData.animate.isPathAnimate){
              this.playGsapPath(gsap, componentData, pathDom);
            }else{
              this.playGsap(gsap, componentData, pathDom);
            }
          }
        }, this.siteInfo.reloadTime)
      }else{
        if(componentData.animate.isPathAnimate){
          this.playGsapPath(gsap, componentData, pathDom);
        }else{
          this.playGsap(gsap, componentData, pathDom);
        }
      }
    },
    loadAllImgPlayGsapStagger(gsap, componentData){
      let this_ = this;
      this.loadImgCompId[componentData.id] = {
        loadImgsNum: 0,
        loadedImgsNum: 0,
      }

      loadImgs(componentData, true);
      
      this["loadImgsCb-" + componentData.id] = window.setInterval(() => {
        loadImgs(componentData, false);
        if(this.loadImgCompId[componentData.id].loadedImgsNum >= this.loadImgCompId[componentData.id].loadImgsNum){
          window.clearInterval(this["loadImgsCb-" + componentData.id]);
          this.playGsapStagger(gsap, componentData);
        }
      }, this.siteInfo.reloadTime)

      function loadImgs(componentData_, isAddNum){
        if(componentData_.components && componentData_.components.length > 0){
          _.forEach(componentData_.components, (compData_) => {
            loadImgs(compData_, isAddNum);
          })
        }
        if(componentData_.cid == COMPONENT_TYPES.wb_img || componentData_.cid == COMPONENT_TYPES.wb_head || componentData_.cid == COMPONENT_TYPES.wb_common_list){
          if(isAddNum){
            this_.loadImgCompId[componentData.id].loadImgsNum++;
          }
          if(isHasOwnProperty(componentData_.commonAttr, 'isLoadedImg') && componentData_.commonAttr.isLoadedImg){
            this_.loadImgCompId[componentData.id].loadedImgsNum++;
          }
        }
      }
    },
    playGsap(gsap, componentData, pathDom){
      const gsapOptionStr = componentData.animate.gsap.options;
      if(gsapOptionStr && isJSON(gsapOptionStr)){
        const gsapAttr = componentData.animate.gsap;
        const tl = gsap.timeline();
        let gsapOptions = JSON.parse(gsapOptionStr);
        if(_.isArray(gsapOptions)) {
          _.forEach(gsapOptions, (gsapOption_) => {
            let gsapOption = this.setGsapAttr(gsapOption_, gsapAttr);
            tl.to(pathDom, gsapOption);
          })
        } else{
          let gsapOption = this.setGsapAttr(gsapOptions, gsapAttr);
          tl.to(pathDom, gsapOption);
        }
        this.gsapPaths[componentData.id] = tl;
      }
    },
    setGsapAttr(gsapOption_, gsapAttr) {
      let gsapOption = gsapOption_;
      gsapOption.ease = gsapAttr.ease;
      gsapOption.yoyo = gsapAttr.yoyo;
      gsapOption.repeat = parseFloat(gsapAttr.repeat);
      gsapOption.duration = isHasOwnProperty(gsapOption_, 'duration') ? parseFloat(gsapOption_.duration): parseFloat(gsapAttr.durations);
      if(isHasOwnProperty(gsapOption_, 'x')) { 
        gsapOption.x = gsapOption_.x/MOBILE_WID_HEI.adaptiveScale;
      }
      if(isHasOwnProperty(gsapOption_, 'y')) { 
        gsapOption.y = gsapOption_.y/MOBILE_WID_HEI.adaptiveScale;
      }
      return gsapOption
    },
    playGsapPath(gsap, componentData, pathDom){
      // pathDom.style.transform = 'translate(0, 0)';
      let tl = this.gsapPaths[componentData.id];
      if(tl){
        if(this.siteAttrs.pageType == PAGE_TYPE.long){
          if(tl.isActive()){
            return
          }
        }else{
          if(tl.isActive()){
            tl.kill();
          }
        }
        tl.invalidate();
        tl.restart();
        return
      }
      const gsapAttr = componentData.animate.gsap;
      const path = componentData.animate.path;
      const attrs = JSON.parse(path.attrs);
      const repeat = parseInt(gsapAttr.repeat);
      const durations = gsapAttr.durations.split(",");
      let ease = 'power3.inOut';
      if(gsapAttr.ease){
        if(gsapAttr.ease === 'none'){
          ease = gsapAttr.ease;
        }else{
          ease = gsapAttr.ease + '.' + gsapAttr.easeInOut;
        }
      }
      const defaultDuration = parseInt(durations[0]);
      const conAttr = componentData.conAttr;
      if(path.isPathBezier){
        let positions_ = [];
        _.forEach(attrs, (attr) => {
          let x_ = attr.x - componentData.conAttr.left;
          let y_ = attr.y - componentData.conAttr.top;
          const xx = Math.abs(x_ - conAttr.left) < 5 ? 0 : x_/MOBILE_WID_HEI.adaptiveScale;
          const yy = componentData.isInGroup || Math.abs(y_ - conAttr.top) < 5 ? 0 : y_/MOBILE_WID_HEI.adaptiveScale;
          let obj = { x: parseInt(xx), y: parseInt(yy) };
          if(isHasOwnProperty(attr, 'alpha')){
            obj.alpha = attr.alpha;
          }
          if(isHasOwnProperty(attr, 'scale')){
            obj.scale = attr.scale;
          }
          positions_.push(obj);
        })
        gsap.set(pathDom, {
          transformOrigin: "center",
        })
        gsap.to(pathDom, {
          repeat: repeat, 
          yoyo: gsapAttr.yoyo,
          duration: defaultDuration + Math.random(),
          motionPath: {
            path: positions_,
            autoRotate: path.autoRotate ? path.autoRotate : false,
            curviness: path.curviness ? path.curviness : 1,
          },
          ease: ease,
          onComplete: () => {
            if(gsapAttr.isOnComplete){
              EventBus.$emit("itemClick", {id: componentData.id, index: -1})
            }
          }
        })
      }else{
        tl = gsap.timeline({
          repeat: repeat, 
          yoyo: gsapAttr.yoyo,
          defaults: { duration: defaultDuration, ease: ease },
          onComplete: () => {
            if(gsapAttr.isOnComplete){
              EventBus.$emit("itemClick", {id: componentData.id, index: -1})
            }
          }
        });
        _.forEach(attrs, (attr, index) => {
          const duration = parseInt(durations[index]);
          const xx = Math.abs(attr.x - conAttr.left) < 5 ? 0 : attr.x/MOBILE_WID_HEI.adaptiveScale;
          const yy = componentData.isInGroup || Math.abs(attr.y - conAttr.top) < 5 ? 0 : attr.y/MOBILE_WID_HEI.adaptiveScale;
          tl.to(pathDom, {
            duration: duration ? duration : defaultDuration,
            alpha: isHasOwnProperty(attr, 'alpha') ? attr.alpha : 1,
            scale: isHasOwnProperty(attr, 'scale') ? attr.scale : 1,
            delay: isHasOwnProperty(attr, 'delay') ? attr.delay : 0,
            x: parseInt(xx),
            y: parseInt(yy),
          });
        })
      }
      this.gsapPaths[componentData.id] = tl;
    },
    playGsapStagger(gsap, componentData){
      let tl = this.gsapStaggers[componentData.id];
      if(tl){
        if(this.siteAttrs.pageType == PAGE_TYPE.long){
          if(tl.isActive()){
            return
          }
        }else{
          if(tl.isActive()){
            tl.kill();
          }
        }
        tl.invalidate();
        tl.restart();
        return
      }
      const commonAttr = componentData.commonAttr;
      let repeat = false;
      let yoyo = false;
      if(commonAttr.isRepeat){
        repeat = -1;
        tl = gsap.timeline({
          repeat: repeat, 
          repeatDelay: 1,
          // onComplete: () => {
          // },
        });
        yoyo = true;
      }else{
        // tl = gsap;
        repeat = 0;
        yoyo = false;
      }

      const groupAnimateClassName = componentData.commonAttr.groupAnimateClass;
      let ease = 'power3.inOut';
      if(commonAttr.ease){
        if(commonAttr.ease === 'none'){
          ease = commonAttr.ease;
        }else{
          ease = commonAttr.ease + '.' + commonAttr.easeInOut;
        }
      }
      const params = {
        opacity: commonAttr.opacity ? commonAttr.opacity : 0,
        scale: commonAttr.scale ? commonAttr.scale : 0.1,
        ease: ease,
        x: commonAttr.offsetX,
        y: commonAttr.offsetY,
        yoyo: yoyo, 
        repeat: repeat,
        stagger: {
          from: commonAttr.from ? commonAttr.from : "random",
          each: commonAttr.intervalTime ? commonAttr.intervalTime : 0.1,
          axis: commonAttr.axis ? commonAttr.axis : '',
          grid: "auto",
        },
      }
      if(commonAttr.isRepeat){
        tl.from("." + groupAnimateClassName, params);
      }else{
        // params.onComplete = () => {
        // };
        tl = gsap.from("." + groupAnimateClassName, params);
      }
      this.gsapStaggers[componentData.id] = tl;
    },
    playGsapSplitText(gsap, textDoms){
      _.forEach(textDoms, (dom) => {
        const componentData = this.componentMap[dom.getAttribute('data-id')];

        let tl = this.gsapSplitTexts[componentData.id];
        if(tl){
          if(this.siteAttrs.pageType == PAGE_TYPE.long){
            if(tl.isActive()){
              return
            }
          }else{
            if(tl.isActive()){
              tl.kill();
            }
          }
          tl.invalidate();
          tl.restart();
          return
        } 

        tl = gsap.timeline();
        let mySplitText = new window.SplitText(dom, {
          type: "words,chars"
        });
        let chars = mySplitText.chars; //an array of all the divs that wrap each character

        gsap.set(dom, {
          perspective: 400
        });

        tl.from(chars, {
          duration: 0.8,
          opacity: 0,
          scale: 0,
          y: 80,
          rotationX: 180,
          transformOrigin: "0% 50% -50",
          ease: "back",
          stagger: 0.01
        }, "+=0");
        this.gsapSplitTexts[componentData.id] = tl;
      })
    },
    clearFirstAnimates(currentPageIndex){
      window.clearInterval(this.resetAnimateClassCb);
      _.forEach(this.pages, (page, pageIndex) => {
        if(pageIndex == currentPageIndex + 1){
          const currentPageDom = document.getElementById('page-' + (pageIndex+1));
          if(currentPageDom){
           this.resetAnimateClassCb = window.setInterval(() => {
              let elements = currentPageDom.getElementsByClassName("scroll-animate");
              if(elements.length > 0 && elements[0].style['-webkit-animation-name']){
                window.clearInterval(this.resetAnimateClassCb);
                _.forEach(elements, (element) => {
                  // element.style.visibility = 'hidden';
                  element.style['-webkit-animation-name'] = '';
                });
              }
            }, this.siteInfo.reloadTime)
          }
        }
      })
    },
  }
}